package com.flute.icrawler.framework.executor;

import java.util.HashMap;
import java.util.Set;

import org.apache.log4j.Logger;

import com.flute.icrawler.app.processor.AbstractProcessor;
import com.flute.icrawler.config.CrawlConfig;
import com.flute.icrawler.config.CrawlConfigUtil;
import com.flute.icrawler.framework.framework.LocalCrawlUrlPool;
import com.flute.tools.timer.IntervalExecutor;

/**
 * 执行器的管理容器
 * 
 * @author Administrator
 * 
 */
public class ExecutorMananger {
	/**
	 * 每个processor对应一个ProcessorExecutor
	 */
	private HashMap<AbstractProcessor, ProcessorExecutor> executorMap;
	private static Logger logger = Logger.getLogger(ExecutorMananger.class);
	private ManagerLogger executorLogger;

	public ExecutorMananger(CrawlConfig crawlConfig,
			LocalCrawlUrlPool localCrawlUrlPool) {
		this.executorMap = new HashMap<AbstractProcessor, ProcessorExecutor>();
		this.executorLogger = new ManagerLogger();
		this.executorLogger.setName("Mananger Logger");
		// 设置为框架打印周期的10倍
		executorLogger.setInterval(CrawlConfigUtil.getBaseConfig()
				.getFrameworkPrintInterval() * 1000 * 10);
		// executorLogger.setInterval(2000);
		executorLogger.start();

		// 给每个不同的IProcessor各注册一个ProcessorExecutor执行器
		for (AbstractProcessor processor : crawlConfig.getProcessorConfig()
				.getAbstractProcessors()) {
			registerExecutor(processor, localCrawlUrlPool);
		}
	}

	/**
	 * 注册processor的执行器
	 * 
	 * @param processor
	 *            处理器
	 * @param pool
	 *            正在处理的url容器
	 */
	public void registerExecutor(AbstractProcessor processor,
			LocalCrawlUrlPool pool) {

		synchronized (executorMap) {
			ProcessorExecutor executor = new ProcessorExecutor(processor, pool);

			executor.setMinCount(processor.minThreadCount);
			executor.setMaxCount(processor.maxThreadCount);

			this.executorMap.put(processor, executor);
		}

	}

	/**
	 * 调度所有的执行器
	 */
	public void run() {
		for (ProcessorExecutor executor : executorMap.values()) {
			executor.execute();
		}
	}

	public ProcessorExecutor getProcessorExecutor(AbstractProcessor processor) {
		return executorMap.get(processor);
	}

	public Set<AbstractProcessor> getProcessors() {
		return executorMap.keySet();
	}

	public ProcessorExecutor[] getProcessorExecutors() {
		return executorMap.values().toArray(new ProcessorExecutor[] {});
	}

	class ManagerLogger extends IntervalExecutor {

		@Override
		public void execute() {
			synchronized (executorMap) {
				for (AbstractProcessor processor : executorMap.keySet()) {
					logger.info(processor.getName() + "  count:"
							+ executorMap.get(processor).getAliveCount());
				}
			}
		}

	}

	public void setFinished(boolean isFinished) {
		executorLogger.setFinish(isFinished);
	}
}
